﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace TuyennvLibrary.SqlClient
{
    public abstract class BaseSort<T> : BaseModel<T> where T : new()
    {
        public List<T> ChangeWeight(List<T> source, int id, int weight)
        {
            T obj = new T();
            int last_index = -1;
            int start_index = -1;
            bool isGreaterthan_thutu = true;
            int InitThutu = weight;
            bool checkid = false;
            bool check_start_index = false, check_last_index = false;
            for (int i = 0; i < source.Count; i++)
            {
                if (CheckWeight(source[i], weight) && !check_start_index)
                {
                    check_start_index = true;
                    start_index = i;

                }
                if ((check_id(source[i], id) || (CheckWeight(source[i], weight) && checkid)) && !check_last_index)
                {
                    if (check_id(source[i], id))
                        checkid = true;
                    obj = source[i];
                    last_index = i;
                    if (isGreaterthan_thutu)
                    {
                        check_last_index = true;

                    }
                    else
                    {
                        if (CheckWeight(source[i], weight))
                            check_last_index = true;
                    }
                    if (!check_start_index)
                    {
                        start_index = i;
                        check_start_index = true;
                        if (getWeight(source[start_index]) < weight)
                        {
                            isGreaterthan_thutu = false;
                            check_last_index = false;
                        }
                    }
                }
                if (check_start_index && check_last_index)
                    break;
            }
            //if (!isGreaterthan_thutu && (getUutien(source[start_index]) == getUutien(source[(start_index-1>0)?start_index-1:0])+1))
            //{
            //    thutu = getUutien(source[start_index]);
            //}
            if (!isGreaterthan_thutu)
            {
                weight = getWeight(source[start_index]);
            }
            //source.RemoveAt(last_index);

            if (isGreaterthan_thutu)
            {
                source.Insert(start_index, obj);
                for (int i = start_index; i <= last_index; i++)
                {
                    //source[i].uutien = thutu++;
                    SetUpWeight(source[i], weight++);
                }
                source.RemoveAt(last_index + 1);
            }
            else
            {
                for (int i = last_index; i >= start_index; i--)
                {
                    //source[i].uutien = thutu++;
                    SetUpWeight(source[i], weight++);
                }
            }

            int pos = last_index;
            while ((pos < source.Count - 1) && getWeight(source[pos + 1]) != weight)
            {
                pos++;
                SetUpWeight(source[pos], weight++);
            }
            index_out = pos;
            return source;
        }
        public List<T> ChangeWeightDESC(List<T> source, int id, int weight)
        {
            T obj = new T();
            int last_index = -1;
            int start_index = -1;
            bool isGreaterthan_thutu = true;
            int InitThutu = weight;
            bool checkid = false;
            bool check_start_index = false, check_last_index = false;
            for (int i = 0; i < source.Count; i++)
            {
                if (CheckWeightDESC(source[i], weight) && !check_start_index)
                {
                    check_start_index = true;
                    start_index = i;

                }
                if ((check_id(source[i], id) || (CheckWeightDESC(source[i], weight) && checkid)) && !check_last_index)
                {
                    if (check_id(source[i], id))
                        checkid = true;
                    obj = source[i];
                    last_index = i;
                    if (isGreaterthan_thutu)
                    {
                        check_last_index = true;

                    }
                    else
                    {
                        if (CheckWeightDESC(source[i], weight))
                            check_last_index = true;
                    }
                    if (!check_start_index)
                    {
                        start_index = i;
                        check_start_index = true;
                        if (getWeight(source[start_index]) < weight)
                        {
                            isGreaterthan_thutu = false;
                            check_last_index = false;
                        }
                    }
                }
                if (check_start_index && check_last_index)
                    break;
            }
            //if (!isGreaterthan_thutu && (getUutien(source[start_index]) == getUutien(source[(start_index-1>0)?start_index-1:0])+1))
            //{
            //    thutu = getUutien(source[start_index]);
            //}
            if (!isGreaterthan_thutu)
            {
                weight = getWeight(source[start_index]);
            }
            //source.RemoveAt(last_index);

            if (isGreaterthan_thutu)
            {
                source.Insert(start_index, obj);
                for (int i = start_index; i <= last_index; i++)
                {
                    //source[i].uutien = thutu++;
                    SetUpWeight(source[i], weight--);
                }
                source.RemoveAt(last_index + 1);
            }
            else
            {
                for (int i = last_index; i >= start_index; i--)
                {
                    //source[i].uutien = thutu++;
                    SetUpWeight(source[i], weight--);
                }
            }

            int pos = last_index;
            while ((pos < source.Count - 1) && getWeight(source[pos + 1]) != weight)
            {
                pos++;
                SetUpWeight(source[pos], weight--);
            }
            index_out = pos;
            return source;
        }
        private bool CheckWeight(T obj, int weight)
        {
            if (getWeight(obj) >= weight || weight == 0)
                return true;
            return false;
        }
        private bool CheckWeightDESC(T obj, int weight)
        {
            if (getWeight(obj) <= weight || weight == 0)
                return true;
            return false;
        }
        private bool check_id(T obj, object id)
        {
            long id_temp = long.Parse(getId(obj).ToString());
            long id_result = long.Parse(id.ToString());
            if (id_temp == id_result)
                return true;
            return false;
        }
        public abstract void SetUpWeight(T obj, int weight);
        public virtual bool UpdateWeightForList(List<T> list, string fieldWeight, string fieldID)
        {
            try
            {
                for (int i = 0; i <= index_out; i++)
                {
                    T item = list[i];
                    string sql = "update " + table + " set " + fieldWeight + "=" + getWeight(item) + " where " + fieldID + "=" + getId(item);
                    DB.ExecuteQuery(sql, null);

                }
                return true;
            }
            catch (Exception)
            {
            }
            return false;
        }
        public abstract int getWeight(T obj);
        public abstract object getId(T obj);
    }

}